﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wormhole.Engine.Communication.Messages
{
	public class CardMessage : Message
	{
		#region Constants
		/// <summary>
		/// The maximum number of cards to send in an indivudual message.
		/// </summary>
		public const int DECK_BUFFER = 10;
		#endregion

		#region Properties

		#region Deck
		/// <summary>
		/// The deck of cards.
		/// </summary>
		public Deck Deck { get; set; }
		#endregion

		#endregion

		#region Constructor
		/// <summary>
		/// Initialize a new instance of the class with the values provided.
		/// </summary>
		/// <param name="deck">The collection of cards.</param>
		/// <param name="action">The action.</param>
		public CardMessage(Deck deck, Actions action)
		{
			this.Deck = deck;
			this.Action = action;
		}

		/// <summary>
		/// Initialize an insance of the class from it's string representation.
		/// </summary>
		/// <param name="message">The string message.</param>
		/// <param name="action">The message action.</param>
		public CardMessage(string message, Actions action)
		{
			this.Action = action;
			this.Parse(message);
		}
		#endregion

		#region To String
		/// <summary>
		/// Convert the message to a string that can be send via the communications channel.
		/// </summary>
		/// <returns>Returns the string representation of the message.</returns>
		public override string ToString()
		{
			// return the message
			return string.Format("{0}|{1}", EnumConvertor<Actions>.ToString(this.Action), this.Deck.ToString());
		}
		#endregion

		#region Parse
		/// <summary>
		/// Parse the string representation of the message.
		/// </summary>
		/// <param name="message">The string message to parse,</param>
		protected void Parse(string message)
		{
			string[] messageParts = message.Split('|');

			if ((messageParts[1] != null) && (messageParts[1].Length > 0))
			{
				this.Deck = new Deck(messageParts[1]);
			}
			else
			{
				this.Deck = new Deck();
			}
		}
		#endregion

		#region Create Messages
		/// <summary>
		/// Create the buffered messages that will be used to communicate the deck of cards.
		/// </summary>
		/// <param name="deck">The complete deck of cards.</param>
		/// <returns>A collection of messages to used to send the deck over the communications channel.</returns>
		public static List<CardMessage> CreateMessages(Deck deck)
		{
			List<CardMessage> messages = new List<CardMessage>();

			if (deck.Count > 0)
			{
				CardMessage currentMessage = null;
				
				// add the cards
				for (int i = 0; i < deck.Count; i++)
				{
					// create a new message if required
					if (i % DECK_BUFFER == 0)
					{
						currentMessage = new CardMessage(new Deck(), Actions.ContinueDeck);
						messages.Add(currentMessage);
					}

					// add the card to the deck
					currentMessage.Deck.Add(deck[i]);
				}

				// set the start and end deck message
				messages.First().Action = Actions.NewDeck;
				messages.Last().Action = Actions.EndDeck;

			}
			return messages;
		}
		#endregion
	}
}
